/*
 * Copyright 2010-2011 Mike Novak <michael.novakjr@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.codeversed.plugins.buzz.util;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.Bundle;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.TimeZone;

import oauth.signpost.OAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;

import com.larvalabs.slidescreen.PluginConstants;
import com.larvalabs.slidescreen.PluginUtils;

import com.codeversed.plugins.buzz.activity.BuzzDetailActivity;
import com.codeversed.plugins.buzz.net.HttpResponseException;
import com.codeversed.plugins.buzz.util.Constants;

public class BuzzUtils {

    public static Cursor requestConsumptionFeed(Context context, String token, String tokenSecret) throws Exception {
        OAuthConsumer consumer = new CommonsHttpOAuthConsumer("anonymous", "anonymous");
        consumer.setTokenWithSecret(token, tokenSecret);
        
        Bundle params = new Bundle();
        params.putString("alt", "json");
        
        if (!Constants.BUZZ_API_KEY.equals("API_AUTO_INSERTED_HERE")) {
            params.putString("key", Constants.BUZZ_API_KEY);
        }
        
        String resp = null;
        
        try {
            resp = HttpUtils.openUrl(Constants.BUZZ_CONSUMPTION, HttpUtils.METHOD_GET, null, params, null, consumer); 
        } catch (HttpResponseException e) {
            Log.e(Constants.LOG_TAG, "Connection error: " + e.toString());
            return null;
        }   
            
        MatrixCursor cursor = new MatrixCursor(PluginConstants.FIELDS_ARRAY);
        
        try {
            JSONObject obj = new JSONObject(resp).getJSONObject("data");
            JSONArray arr = obj.getJSONArray("items");
            int size = arr.length();
            
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
            TimeZone tz = TimeZone.getDefault();
            Intent intent;
            Bundle extras;
            
            for (int i = 0; i < size; i++) {
                extras = new Bundle();
                intent = new Intent(Intent.ACTION_MAIN);
                intent.setComponent(new ComponentName("com.codeversed.plugins.buzz", 
                        "com.codeversed.plugins.buzz.activity.BuzzDetailActivity"));
                        
                JSONObject item = arr.getJSONObject(i);
                
                MatrixCursor.RowBuilder builder = cursor.newRow();
                                
                Date published = format.parse(item.getString("published"));
                    
                builder.add(item.getString("id"));
                builder.add(item.getJSONObject("actor").getString("name"));
                builder.add(published.getTime() + tz.getRawOffset() + tz.getDSTSavings());
                builder.add(published.getTime() + tz.getRawOffset() + tz.getDSTSavings());
                builder.add(item.getString("title"));
                builder.add(" ");
                    
                /* build intent for details. */
                extras.putString("id", item.getString("id"));
                extras.putString("actor", item.getJSONObject("actor").getString("name"));
                extras.putLong("published", published.getTime() + tz.getRawOffset() + tz.getDSTSavings());
                extras.putString("title", item.getString("title"));
                extras.putString("content", item.getJSONObject("object").getString("content"));
                extras.putString("avatar", item.getJSONObject("actor").getString("thumbnailUrl"));
                extras.putString("comment_count", item.getJSONObject("links").getJSONArray("replies").getJSONObject(0).getString("count"));
                
                if (item.has("geocode")) {
                    extras.putString("geocode", item.getString("geocode"));
                }
                    
                if (item.has("address")) {
                    extras.putString("address", item.getString("address"));
                }
                    
                if (item.has("source")) {
                    extras.putString("source", item.getJSONObject("source").getString("title"));
                }
                
                /* if the content is a photo grab the preview image. */
                if (item.getJSONObject("object").has("attachments")) {
                    JSONArray attachments = item.getJSONObject("object").getJSONArray("attachments");
                    int numAttachments = attachments.length();
                    ArrayList<String> previews = new ArrayList<String>();
                    ArrayList<String> images = new ArrayList<String>();
                    
                    Log.d(Constants.LOG_TAG, "Number of attachments: " + numAttachments);

                    for (int j = 0; j < numAttachments; j++) {
                        JSONObject attachment = attachments.getJSONObject(j);
                        
                        if (attachment.getString("type").equals("photo")) {
                            previews.add(attachment.getJSONObject("links").getJSONArray("preview").
                                    getJSONObject(0).getString("href"));

                            images.add(attachment.getJSONObject("links").getJSONArray("enclosure").
                                    getJSONObject(0).getString("href"));
                        }
                    }
                    
                    if (!previews.isEmpty()) {
                        String[] p = new String[previews.size()];
                        extras.putStringArray("photos", previews.toArray(p));
                    }

                    if (!images.isEmpty()) {
                        String[] p = new String[images.size()];
                        extras.putStringArray("full_photos", images.toArray(p));
                    }
                }
                
                intent.putExtras(extras);                
                builder.add(PluginUtils.encodeIntents(intent));
            }
        } catch (JSONException e) {
            Log.e(Constants.LOG_TAG, "JSON Parse error: " + e.toString());
        } catch (ParseException e) {
            Log.e(Constants.LOG_TAG, "Date Parse error: " + e.toString());
        }
        
        return cursor;
    }
    
    public static Cursor requestActivityComments(String actId, String token, String tokenSecret) throws Exception {
        OAuthConsumer consumer = new CommonsHttpOAuthConsumer("anonymous", "anonymous");
        consumer.setTokenWithSecret(token, tokenSecret);
        
        Bundle params = new Bundle();
        params.putString("alt", "json");
        
        if (!Constants.BUZZ_API_KEY.equals("API_AUTO_INSERTED_HERE")) {
            params.putString("key", Constants.BUZZ_API_KEY);
        }
        
        String resp = null;
        
        try {
            resp = HttpUtils.openUrl(String.format(Constants.BUZZ_COMMENTS, actId), HttpUtils.METHOD_GET, null, params, null, consumer); 
        } catch (HttpResponseException e) {
            Log.e(Constants.LOG_TAG, "Connection error: " + e.toString());
            return null;
        }
        
        MatrixCursor cursor = new MatrixCursor(Constants.COMMENT_FIELDS);
        
        try {
            JSONObject obj = new JSONObject(resp).getJSONObject("data");
            JSONArray items = obj.getJSONArray("items");
            int size = items.length();
            
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
            TimeZone tz = TimeZone.getDefault();
            
            for (int i = 0; i < size; i++) {
                JSONObject item = items.getJSONObject(i);
                Date posted = format.parse(item.getString("published"));
                
                MatrixCursor.RowBuilder builder = cursor.newRow();
                builder.add(i);
                builder.add(item.getJSONObject("actor").getString("name"));
                builder.add(item.getString("content"));
                builder.add(posted.getTime() + tz.getRawOffset() + tz.getDSTSavings());
            }
        } catch (JSONException e) {
            Log.e(Constants.LOG_TAG, "JSON Parse error: " + e.toString());
        } catch (ParseException e) {
            Log.e(Constants.LOG_TAG, "Date parse error: " + e.toString());
        }
        
        return cursor;
    }
    
    public static boolean setLikeActivity(boolean like, String actId, String token, String tokenSecret) throws Exception {
        OAuthConsumer consumer = new CommonsHttpOAuthConsumer("anonymous", "anonymous");
        consumer.setTokenWithSecret(token, tokenSecret);
        
        Bundle params = new Bundle();
        params.putString("alt", "json");
        
        if (!Constants.BUZZ_API_KEY.equals("API_AUTO_INSERTED_HERE")) {
            params.putString("key", Constants.BUZZ_API_KEY);
        }
        
        String resp = null;
        
        int method = HttpUtils.METHOD_PUT;
        
        if (!like) {
            method = HttpUtils.METHOD_DELETE;
        }
        
        try {
            resp = HttpUtils.openUrl(String.format(Constants.BUZZ_LIKE_UNLIKE, actId), method, null, params, null, consumer); 
            return true;
        } catch (HttpResponseException e) {
            Log.e(Constants.LOG_TAG, "Connection error: " + e.toString());
            return false;
        }
    }
    
    public static boolean composeNewActivity(String postContent, String token, String tokenSecret) throws Exception {
        OAuthConsumer consumer = new CommonsHttpOAuthConsumer("anonymous", "anonymous");
        consumer.setTokenWithSecret(token, tokenSecret);
        
        Bundle params = new Bundle();
        params.putString("alt", "json");
        
        if (!Constants.BUZZ_API_KEY.equals("API_AUTO_INSERTED_HERE")) {
            params.putString("key", Constants.BUZZ_API_KEY);
        }
        
        Bundle headers = new Bundle();
        headers.putString("Content-Type", "application/json");
        
        try {
            JSONObject obj = new JSONObject();
            obj.put("data", new JSONObject().put("object", new JSONObject().put("type", "note").put("content", postContent)));
            
            String resp = HttpUtils.openUrl(Constants.BUZZ_ACTIVITY, HttpUtils.METHOD_POST, obj.toString(), params, headers, consumer);
            
            if (resp == null) {
                return false;
            }
            
            return true;
        } catch (HttpResponseException e) {
            Log.e(Constants.LOG_TAG, "Error posting new activity: " + e.toString());
            return false;
        } catch (JSONException e) {
            Log.e(Constants.LOG_TAG, "Error posting new activity: " + e.toString());
            return false;
        }
    }
    
    public static boolean postComment(String comment, String actId, String token, String tokenSecret) throws Exception {
        OAuthConsumer consumer = new CommonsHttpOAuthConsumer("anonymous", "anonymous");
        consumer.setTokenWithSecret(token, tokenSecret);
        
        Bundle params = new Bundle();
        params.putString("alt", "json");
        
        if (!Constants.BUZZ_API_KEY.equals("API_AUTO_INSERTED_HERE")) {
            params.putString("key", Constants.BUZZ_API_KEY);
        }
        
        Bundle headers = new Bundle();
        headers.putString("Content-Type", "application/json");
        
        try {
            JSONObject obj = new JSONObject();
            obj.put("data", new JSONObject().put("content", comment));
            
            String resp = HttpUtils.openUrl(String.format(Constants.BUZZ_COMMENTS, actId), HttpUtils.METHOD_POST, 
                    obj.toString(), params, headers, consumer);
            
            if (resp == null) {
                return false;
            }
            
            return true;
        } catch (HttpResponseException e) {
            Log.e(Constants.LOG_TAG, "Error posting comment: " + e.toString());
            return false;
        } catch (JSONException e) {
            Log.e(Constants.LOG_TAG, "Error posting comment: " + e.toString());
            return false;
        }
    }
    
    public static boolean reshareActivity(String note, String actId, String token, String tokenSecret) throws Exception {
        OAuthConsumer consumer = new CommonsHttpOAuthConsumer("anonymous", "anonymous");
        consumer.setTokenWithSecret(token, tokenSecret);
        
        Bundle params = new Bundle();
        params.putString("alt", "json");
        
        if (!Constants.BUZZ_API_KEY.equals("API_AUTO_INSERTED_HERE")) {
            params.putString("key", Constants.BUZZ_API_KEY);
        }
        
        Bundle headers = new Bundle();
        headers.putString("Content-Type", "application/json");
        
        try {
            JSONObject obj = new JSONObject();
            JSONObject data = obj.put("data", new JSONObject()).getJSONObject("data");
            
            if (note != null) {
                data.put("annotation", note);
            }
            
            data.put("verbs", new JSONArray().put("share"));
            data.put("object", new JSONObject().put("id", actId));
            
            String resp = HttpUtils.openUrl(Constants.BUZZ_ACTIVITY, HttpUtils.METHOD_POST, obj.toString(), params, headers, consumer);
            
            if (resp == null) {
                return false;
            }
            
            return true;
        } catch (HttpResponseException e) {
            Log.e(Constants.LOG_TAG, "Error resharing post: " + e.toString());
            return false;
        } catch (JSONException e) {
            Log.e(Constants.LOG_TAG, "Error resharing post: " + e.toString());
            return false;
        }
    }
}
